package com.heima.comment.service.impl;

import com.heima.apis.article.ApArticleClient;
import com.heima.apis.user.IUserClient;
import com.heima.apis.wemedia.IWemediaClient;
import com.heima.comment.service.CommentRepayService;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.comment.dtos.CommentRepayDto;
import com.heima.model.comment.dtos.CommentRepayLikeDto;
import com.heima.model.comment.dtos.CommentRepaySaveDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentLike;
import com.heima.model.comment.pojos.ApCommentRepay;
import com.heima.model.comment.vos.ApCommentRepayVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.utils.thread.AppThreadLocalUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CommentRepayServiceImpl implements CommentRepayService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IWemediaClient iWemediaClient;

    @Autowired
    private IUserClient iUserClient;

    @Autowired
    private ApArticleClient apArticleClient;

    /**
     * 评论回复
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveCommentRepay(CommentRepaySaveDto dto) {
        //参数校验
        if (dto==null || dto.getCommentId()==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //获取用户
        Integer apUserId = AppThreadLocalUtils.getUser().getId();
        if (apUserId==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN,"请登录后评论!");
        }
        //获取文章评论状态
        String commentId = dto.getCommentId();
        ApComment comment = mongoTemplate.findOne(Query.query(Criteria.where("id").is(commentId)), ApComment.class);
        ApArticleConfig articleConfig = apArticleClient.getArticleConfig(comment.getEntryId());
        if (!articleConfig.getIsComment()){
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH,"文章不可评论!");
        }

        String content = dto.getContent();
        if (content.length()>=140){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,
                    "评论文字过长,请不要超过140字!");
        }
        //评论内容校验
        boolean flag=handleCommentScan(content);
        if (!flag){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,
                    "评论中包含敏感词!");
        }
        //回复评论内容
        ApCommentRepay apCommentRepay=new ApCommentRepay();
        //远程调用
        ApUser apUser = iUserClient.getUser(apUserId);
        //设置回复评论
        apCommentRepay.setAuthorId(apUserId);
        apCommentRepay.setAuthorName(apUser.getName());
        apCommentRepay.setCommentId(dto.getCommentId());
        apCommentRepay.setContent(content);
        apCommentRepay.setLikes(0);
        apCommentRepay.setCreatedTime(new Date());
        apCommentRepay.setUpdatedTime(new Date());
        mongoTemplate.save(apCommentRepay);

        // 添加回复数量
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        Integer reply = apComment.getReply();
        reply= reply==null ? 1 : (reply+1);

        Query query=new Query(Criteria.where("id").is(dto.getCommentId()));
        //更新值
        Update update=new Update().set("reply",reply);
        //更新
        mongoTemplate.updateFirst(query,update,ApComment.class);

        return ResponseResult.okResult("");
    }

    /**
     * 校验评论内容
     * @param content
     * @return
     */
    private boolean handleCommentScan(String content) {
        //标记位：假设审核没问题
        boolean flag = true;
        //获取敏感词
        List<WmSensitive> allSensitive = iWemediaClient.getAllSensitive();
        List<String> list = allSensitive.stream().map(wmSensitive -> wmSensitive.getSensitives()).collect(Collectors.toList());
        //1. 初始化敏感词库
        SensitiveWordUtil.initMap(list);
        //2. 进行敏感词匹配
        Map<String, Integer> resMap = SensitiveWordUtil.matchWords(content);
        //结果处理
        if (!resMap.isEmpty()){
            flag = false;
        }
        return flag;
    }



    /**
     * 查询评论回复列表
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(CommentRepayDto dto) {
        //校验参数
        if (dto==null || dto.getCommentId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Query query=new Query();

        Criteria criteria=new Criteria();
        //多条件拼接
        criteria.andOperator(
               Criteria.where("commentId").is(dto.getCommentId()),
               Criteria.where("createdTime").lt(dto.getMinDate())
        );
        //添加条件
        query.addCriteria(criteria);

        int size=10;
        if (dto.getSize()==null)
            dto.setSize(size);
        query.limit(dto.getSize());
        query.skip(0);
        //排序
        query.with(Sort.by(
                Sort.Order.desc("createdTime")
        ));
        List<ApCommentRepay> apCommentRepayList = mongoTemplate.find(query, ApCommentRepay.class);
        //获取用户id
        Integer apUserId = AppThreadLocalUtils.getUser().getId();

        List<ApCommentRepayVo> apCommentRepayVos = new ArrayList<>();

        for (ApCommentRepay apCommentRepay : apCommentRepayList) {
            ApCommentRepayVo apCommentRepayVo = new ApCommentRepayVo();
            BeanUtils.copyProperties(apCommentRepay,apCommentRepayVo);

            Criteria criteria1=new Criteria();
            //多条件拼接
            criteria1.andOperator(
                    Criteria.where("commentId").is(apCommentRepay.getId()),
                    Criteria.where("authorId").is(apUserId)
            );
            //点赞 存在
            if(mongoTemplate.exists(Query.query(criteria1),ApCommentLike.class)){
                apCommentRepayVo.setOperation(0);
            }
            apCommentRepayVos.add(apCommentRepayVo);
        }

        return ResponseResult.okResult(apCommentRepayVos);
    }

    /**
     * 点赞/取消点赞
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentRepayLikeDto dto) {
        //校验参数
        if (dto==null || dto.getCommentRepayId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //查询回复评论
        ApCommentRepay apCommentRepay = mongoTemplate.findById(dto.getCommentRepayId(),
                ApCommentRepay.class);
        //获取点赞数
        Integer likes = apCommentRepay.getLikes();
        likes=likes==null? 0: likes;
        //获取用户id
        Integer apUserId = AppThreadLocalUtils.getUser().getId();
        ApCommentLike apCommentLike=new ApCommentLike();
        apCommentLike.setCommentId(dto.getCommentRepayId());
        apCommentLike.setAuthorId(apUserId);
        if (dto.getOperation()==0){
            likes+=1;
            //保存点赞关系
            mongoTemplate.save(apCommentLike);
        }else {
            likes=likes-1<=0?0:likes-1;
            //取消点赞
            Query query=new Query(Criteria.where("commentId").is(dto.getCommentRepayId()));
            mongoTemplate.remove(query,ApCommentLike.class);
        }
        //修改数据
        //更新条件
        Query query=new Query(Criteria.where("id").is(dto.getCommentRepayId()));
        //更新值
        Update update=new Update().set("likes",likes);
        //更新
        mongoTemplate.updateFirst(query,update,ApCommentRepay.class);
        return ResponseResult.okResult("");
    }
}
